package com.yyw.gulimall.product.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yyw.common.constant.product.enums.SpuInfoEnum;
import com.yyw.common.exception.FeignCallException;
import com.yyw.common.exception.RRException;
import com.yyw.common.to.productsearch.AttrTo;
import com.yyw.common.to.productsearch.SpuInfoTo;
import com.yyw.common.utils.PageUtils;
import com.yyw.common.utils.Query;
import com.yyw.common.utils.R;
import com.yyw.gulimall.product.dao.SpuInfoDao;
import com.yyw.gulimall.product.dto.*;
import com.yyw.gulimall.product.entity.*;
import com.yyw.gulimall.product.feign.member.SpuCouponFeign;
import com.yyw.gulimall.product.feign.search.ProductSearchFeign;
import com.yyw.gulimall.product.feign.ware.WareFeignService;
import com.yyw.gulimall.product.service.*;
import com.yyw.gulimall.product.vo.supVo.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * @author 易煜玮
 */
@Service("spuInfoService")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    private final SpuInfoDescService spuInfoDescService;
    private final SpuImagesService spuImagesService;
    private final AttrService attrService;
    private final ProductAttrValueService productAttrValueService;
    private final SpuCouponFeign spuCouponFeign;
    private final SkuInfoService skuInfoService;
    private final SkuImagesService skuImagesService;
    private final SkuSaleAttrValueService skuSaleAttrValueService;
    private final WareFeignService wareFeignService;
    private final BrandService brandService;
    private final CategoryService categoryService;
    private final ProductSearchFeign productSearchFeign;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<SpuInfoEntity> queryWrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        String catelogId = (String) params.get("catelogId");
        String brandId = (String) params.get("brandId");
        String status = (String) params.get("status");
        if (!StringUtils.isEmpty(key)) {
            queryWrapper.lambda().and(e -> {
                e.eq(SpuInfoEntity::getId, key).or().like(SpuInfoEntity::getSpuName, key);
            });
        }
        if (!StringUtils.isEmpty(catelogId)) {
            queryWrapper.lambda().eq(SpuInfoEntity::getCatalogId, catelogId);
        }
        if (!StringUtils.isEmpty(brandId) && !Objects.equals("0", brandId)) {
            queryWrapper.lambda().eq(SpuInfoEntity::getBrandId, brandId);
        }
        if (!StringUtils.isEmpty(status)) {
            queryWrapper.lambda().eq(SpuInfoEntity::getPublishStatus, status);
        }

        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveSpuInfo(SpuInfoVo spuInfoVo) {
        // 1. 保存spu基本信息 pms_spu_info
        SpuInfoEntity spuInfo = new SpuInfoEntity();
        BeanUtils.copyProperties(spuInfoVo, spuInfo);
        spuInfo.setCreateTime(new Date());
        this.save(spuInfo);

        // 2. 保存Spu的描述图片 pms_spu_info_desc
        SpuInfoDescEntity descEntity = SpuInfoDescEntity.builder()
                .decript(String.join(",", spuInfoVo.getDecript()))
                .spuId(spuInfo.getId())
                .build();
        spuInfoDescService.save(descEntity);

        //3、保存spu的图片集 pms_spu_images
        if (!CollectionUtils.isEmpty(spuInfoVo.getImages())) {
            spuInfoVo.getImages().forEach(e -> {
                SpuImagesEntity imagesEntity = SpuImagesEntity.builder()
                        .imgUrl(e)
                        .spuId(spuInfo.getId())
                        .build();
                spuImagesService.save(imagesEntity);
            });
        }

        //4、保存spu的规格参数;pms_product_attr_value
        // 拿到该SPU绑定的所有属性
        List<BaseAttrs> baseAttrs = spuInfoVo.getBaseAttrs();
        if (!CollectionUtils.isEmpty(baseAttrs)) {
            baseAttrs.forEach(e -> {
                // 查询属性信息
                AttrEntity attrEntity = attrService.getById(e.getAttrId());
                ProductAttrValueEntity valueEntity = ProductAttrValueEntity.builder()
                        .attrId(e.getAttrId())
                        .attrValue(e.getAttrValues())
                        .attrName(attrEntity.getAttrName())
                        .quickShow(e.getShowDesc())
                        .spuId(spuInfo.getId()).build();
                productAttrValueService.save(valueEntity);
            });
        }

        //5、保存spu的积分信息；gulimall_sms->sms_spu_bounds
        spuInfoVo.getBounds().setSpuId(spuInfo.getId());
        // 远程调用
        R r = spuCouponFeign.save(spuInfoVo.getBounds());
        if (!Objects.equals(r.get("code"), 0)) {
            log.error("远程调用保存SPU积分信息失败");
            throw new FeignCallException("调用失败");
        }

        //6、保存当前spu对应的所有sku信息；
        List<Skus> skus = spuInfoVo.getSkus();
        if (!CollectionUtils.isEmpty(skus)) {
            //6.1）、sku的基本信息；pms_sku_info
            skus.forEach(e -> {
                SkuInfoEntity skuInfo = new SkuInfoEntity();
                BeanUtils.copyProperties(e, skuInfo);
                skuInfo.setBrandId(spuInfoVo.getBrandId());
                skuInfo.setCatalogId(spuInfoVo.getCatalogId());
                skuInfo.setSpuId(spuInfo.getId());
                skuInfo.setSkuDefaultImg(getDefaultImg(e.getImages()));
                skuInfoService.save(skuInfo);


                //6.2）、sku的图片信息；pms_sku_image
                List<Images> images = e.getImages();
                if (!CollectionUtils.isEmpty(images)) {
                    List<SkuImagesEntity> imgs = images.stream().filter(img -> !Objects.equals("", img.getImgUrl()))
                            .map(img -> {
                                SkuImagesEntity imagesEntity = SkuImagesEntity.builder()
                                        .defaultImg(img.getDefaultImg())
                                        .imgUrl(img.getImgUrl())
                                        .skuId(skuInfo.getSkuId()).build();
                                return imagesEntity;
                            }).collect(Collectors.toList());
                    skuImagesService.saveBatch(imgs);
                }


                //6.3）、sku的销售属性信息：pms_sku_sale_attr_value
                List<Attr> attrs = e.getAttr();
                if (!CollectionUtils.isEmpty(attrs)) {
                    attrs.forEach(attr -> {
                        SkuSaleAttrValueEntity attrValueEntity = SkuSaleAttrValueEntity.builder()
                                .attrId(attr.getAttrId())
                                .attrValue(attr.getAttrValue())
                                .attrName(attr.getAttrName())
                                .skuId(skuInfo.getSkuId()).build();
                        skuSaleAttrValueService.save(attrValueEntity);
                    });
                }

                SkuLadderDto ladderDto = null;
                //6.4）、sku的优惠、满减等信息；gulimall_sms->sms_sku_ladder\sms_sku_full_reduction\sms_member_price
                if (e.getFullCount() != 0 || e.getDiscount().compareTo(BigDecimal.ZERO) != 0) {
                    // 6.4.1 保存 商品阶梯价格 满几件打几折
                    // 满几件打几折的折后价
                    BigDecimal priceCount = e.getPrice().multiply(e.getDiscount());
                    ladderDto = SkuLadderDto.builder()
                            .skuId(skuInfo.getSkuId())
                            .fullCount(e.getFullCount())
                            .discount(e.getDiscount())
                            .price(priceCount)
                            .addOther(e.getCountStatus()).build();
                }

                SkuFullReductionDto reductionDto = null;
                if (e.getFullPrice().compareTo(BigDecimal.ZERO) != 0 || e.getReducePrice().compareTo(BigDecimal.ZERO) != 0) {
                    // 6.4.2 保存 商品满减信息 满多少打几折
                    // 满减后打几折的折后价
                    BigDecimal priceRedu = e.getPrice().multiply(e.getReducePrice());
                    reductionDto = SkuFullReductionDto.builder()
                            .skuId(skuInfo.getSkuId())
                            .fullPrice(e.getFullPrice())
                            .reducePrice(e.getReducePrice())
                            .price(priceRedu)
                            .addOther(e.getPriceStatus()).build();
                }

                // 6.4.3 保存 商品会员价格
                List<MemberPriceDto> collect = null;
                if (!CollectionUtils.isEmpty(e.getMemberPrice())) {
                    collect = e.getMemberPrice().stream().filter(mem -> {
                        return mem.getPrice().compareTo(BigDecimal.ZERO) == 1;
                    }).map(memberPrice -> {
                        MemberPriceDto memberPriceDto = MemberPriceDto.builder()
                                .memberPrice(memberPrice.getPrice())
                                .memberLevelId(memberPrice.getId())
                                .memberLevelName(memberPrice.getName())
                                .skuId(skuInfo.getSkuId()).build();
                        return memberPriceDto;
                    }).collect(Collectors.toList());
                }

                // 发起请求，远程调用
                MemFullLaddersDto dto = MemFullLaddersDto.builder()
                        .skuLadderDto(ladderDto)
                        .skuFullReductionDto(reductionDto)
                        .memberPriceDtos(collect).build();
                R r1 = spuCouponFeign.saveSkuRelevant(dto);
                if (!Objects.equals(r1.get("code"), 0)) {
                    log.error("远程调用保存优惠信息失败");
                    throw new FeignCallException("调用失败");
                }
            });
        }
    }

    @Override
    public void up(long spuId) {
        // 2. 封装TO类
        // 2.1 获取所有的SKU信息
        List<SkuInfoEntity> skuInfoList = skuInfoService.list(new QueryWrapper<SkuInfoEntity>().lambda().eq(SkuInfoEntity::getSpuId, spuId));
        if (CollectionUtils.isEmpty(skuInfoList)) {
            throw new RRException("未查到SKU信息，无法上架");
        }
        // 2.2 查询是否有库存
        Map<Long, Boolean> stockMap = null;
        try {
            List<Long> skuIds = skuInfoList.stream().map(e -> e.getSkuId()).collect(Collectors.toList());
            R r = wareFeignService.bulkGetStock(skuIds);
            String data = JSON.toJSONString(r.get("data"));
            List<SkuInfoStockDto> stockDtoList = JSON.parseArray(data, SkuInfoStockDto.class);
            if (!CollectionUtils.isEmpty(stockDtoList)) {
                // 封装 skuid：库存
                stockMap = stockDtoList.stream().collect(Collectors.toMap(SkuInfoStockDto::getSkuId, e -> e.getHasStock()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Map<Long, Boolean> finalStockMap = stockMap;

        // 2.3 查询 brandName; brandImg; catalogName;
        SkuInfoEntity tempEntiy = skuInfoList.get(0);
        BrandEntity brandEntity = brandService.getById(tempEntiy.getBrandId());
        CategoryEntity categoryEntity = categoryService.getById(tempEntiy.getCatalogId());

        // 2.4 查询ProductAttr
        List<AttrTo> attrTos = productAttrValueService.getAttrToBySpuId(spuId);


        // 遍历SKU信息，封装数据
        List<SpuInfoTo> result = skuInfoList.stream().map(e -> {
            SpuInfoTo infoTo = new SpuInfoTo();
            BeanUtils.copyProperties(e, infoTo);
            infoTo.setSkuPrice(e.getPrice());
            infoTo.setSkuImg(e.getSkuDefaultImg());

            // 设置热度
            infoTo.setHotScore(0L);

            // 设置库存 如果因为网络原因请求失败，默认设置为没库存
            if (CollectionUtils.isEmpty(finalStockMap)) {
                infoTo.setHasStock(false);
            } else {
                infoTo.setHasStock(finalStockMap.get(e.getSkuId()));
            }

            // 设置 brandName; brandImg; catalogName;
            infoTo.setBrandName(brandEntity.getName());
            infoTo.setBrandImg(brandEntity.getLogo());
            infoTo.setCatalogName(categoryEntity.getName());

            // 设置Attrs
            infoTo.setAttrs(attrTos);
            return infoTo;
        }).collect(Collectors.toList());

        // 3. 传输给ES保存
        R r = productSearchFeign.saveSkuInfo(result);
        if (!Objects.equals(r.get("code"), "0")) {
            // 1. 修改上架状态
            UpdateWrapper<SpuInfoEntity> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().eq(SpuInfoEntity::getId, spuId).set(SpuInfoEntity::getPublishStatus, SpuInfoEnum.UP.getCode());
            this.update(updateWrapper);
        } else {
            // 上架发生了错误
        }
    }

    /**
     * 找出默认图片
     *
     * @param images
     * @return
     */
    private String getDefaultImg(List<Images> images) {
        String url = "";
        if (!CollectionUtils.isEmpty(images)) {
            for (Images image : images) {
                if (image.getDefaultImg() == 1) {
                    url = image.getImgUrl();
                }
            }
        }
        return url;
    }

}